/*
 * ChatServer.h
 * 
 * 聊天服务器 - 展示框架实战应用
 * 阶段4：Chat Server 实战
 * 
 * 功能：
 * 1. 用户登录
 * 2. 群聊消息（广播）
 * 3. 私聊消息
 * 4. 用户列表查询
 * 5. 用户上下线通知
 */

#pragma once

#include "server/BaseServer.h"
#include "protocol/PacketHeader.h"
#include "chat.pb.h"

#include <muduo/base/Logging.h>
#include <unordered_map>
#include <mutex>
#include <string>

namespace servers {

/**
 * @brief 聊天服务器
 * 
 * 使用 BaseServer 框架实现多人聊天功能
 * 展示框架的实用性和易用性
 */
class ChatServer : public framework::BaseServer {
public:
    explicit ChatServer(const framework::ServerConfig& config)
        : BaseServer(config) {}
    
protected:
    /**
     * @brief 初始化 - 注册所有消息处理器
     */
    bool onInit() override {
        // 注册登录消息处理器
        registerMessageHandler<protocol::LoginRequest>(
            protocol::MSG_LOGIN,
            std::bind(&ChatServer::onLogin, this,
                     std::placeholders::_1,
                     std::placeholders::_2,
                     std::placeholders::_3));
        
        // 注册聊天消息处理器
        registerMessageHandler<protocol::ChatMessage>(
            protocol::MSG_CHAT,
            std::bind(&ChatServer::onChat, this,
                     std::placeholders::_1,
                     std::placeholders::_2,
                     std::placeholders::_3));
        
        // 注册私聊消息处理器
        registerMessageHandler<protocol::PrivateMessage>(
            protocol::MSG_PRIVATE,
            std::bind(&ChatServer::onPrivate, this,
                     std::placeholders::_1,
                     std::placeholders::_2,
                     std::placeholders::_3));
        
        // 注册用户列表查询处理器
        registerMessageHandler<protocol::UserListRequest>(
            protocol::MSG_USER_LIST,
            std::bind(&ChatServer::onUserList, this,
                     std::placeholders::_1,
                     std::placeholders::_2,
                     std::placeholders::_3));
        
        LOG_INFO << "ChatServer: All message handlers registered";
        return true;
    }
    
    /**
     * @brief 启动后回调
     */
    void onStart() override {
        LOG_INFO << "========================================";
        LOG_INFO << "  Chat Server Started Successfully!";
        LOG_INFO << "  Stage 4: Chat Server Implementation";
        LOG_INFO << "========================================";
        LOG_INFO << "Features:";
        LOG_INFO << "  - User Login";
        LOG_INFO << "  - Group Chat (Broadcast)";
        LOG_INFO << "  - Private Chat";
        LOG_INFO << "  - User List Query";
        LOG_INFO << "  - Online/Offline Notifications";
        LOG_INFO << "========================================";
        LOG_INFO << "Ready to accept connections...";
    }
    
    /**
     * @brief 会话连接回调
     */
    void onSessionConnected(const framework::SessionPtr& session) override {
        LOG_INFO << "New client connected: " << session->sessionId();
    }
    
    /**
     * @brief 会话断开回调 - 清理用户数据
     */
    void onSessionDisconnected(const framework::SessionPtr& session) override {
        std::lock_guard<std::mutex> lock(usersMutex_);
        
        auto it = onlineUsers_.find(session->sessionId());
        if (it != onlineUsers_.end()) {
            std::string username = it->second;
            
            LOG_INFO << "User '" << username << "' (Session " 
                     << session->sessionId() << ") disconnected";
            
            // 通知其他用户
            protocol::UserLeftNotify notify;
            notify.set_username(username);
            broadcast(protocol::MSG_USER_LEFT, notify);
            
            // 从在线列表移除
            onlineUsers_.erase(it);
            
            LOG_INFO << "Online users: " << onlineUsers_.size();
        } else {
            LOG_INFO << "Client disconnected: " << session->sessionId() 
                     << " (not logged in)";
        }
    }

private:
    /**
     * @brief 处理登录请求
     */
    void onLogin(const framework::SessionPtr& session,
                const protocol::LoginRequest& request,
                muduo::Timestamp time) {
        std::lock_guard<std::mutex> lock(usersMutex_);
        
        std::string username = request.username();
        
        LOG_INFO << "Login request from session " << session->sessionId()
                 << ", username: " << username;
        
        // 检查用户名是否已存在
        for (const auto& pair : onlineUsers_) {
            if (pair.second == username) {
                // 用户名已存在
                protocol::LoginResponse response;
                response.set_result(1);
                response.set_message("Username already exists!");
                sendToClient(session->sessionId(), protocol::MSG_LOGIN_RESPONSE, response);
                
                LOG_WARN << "Login failed: username '" << username << "' already exists";
                return;
            }
        }
        
        // 保存用户
        onlineUsers_[session->sessionId()] = username;
        
        // 响应客户端
        protocol::LoginResponse response;
        response.set_result(0);
        response.set_message("Welcome to Chat Server!");
        sendToClient(session->sessionId(), protocol::MSG_LOGIN_RESPONSE, response);
        
        LOG_INFO << "User '" << username << "' logged in successfully";
        LOG_INFO << "Online users: " << onlineUsers_.size();
        
        // 通知其他用户
        protocol::UserJoinedNotify notify;
        notify.set_username(username);
        
        // 广播给所有其他用户（除了自己）
        for (const auto& pair : onlineUsers_) {
            if (pair.first != session->sessionId()) {
                sendToClient(pair.first, protocol::MSG_USER_JOINED, notify);
            }
        }
        
        LOG_INFO << "User joined notification sent to " 
                 << (onlineUsers_.size() - 1) << " users";
    }
    
    /**
     * @brief 处理群聊消息
     */
    void onChat(const framework::SessionPtr& session,
               const protocol::ChatMessage& msg,
               muduo::Timestamp time) {
        std::lock_guard<std::mutex> lock(usersMutex_);
        
        // 查找发送者用户名
        auto it = onlineUsers_.find(session->sessionId());
        if (it == onlineUsers_.end()) {
            LOG_WARN << "Chat message from not logged in session: " 
                     << session->sessionId();
            return;
        }
        
        std::string fromUser = it->second;
        
        LOG_INFO << "Chat message from '" << fromUser << "': " << msg.content();
        
        // 构造广播消息
        protocol::ChatMessage broadcastMsg;
        broadcastMsg.set_from(fromUser);
        broadcastMsg.set_content(msg.content());
        broadcastMsg.set_timestamp(time.microSecondsSinceEpoch());
        
        // 广播给所有在线用户
        broadcast(protocol::MSG_CHAT, broadcastMsg);
        
        LOG_INFO << "Chat message broadcasted to " << onlineUsers_.size() << " users";
    }
    
    /**
     * @brief 处理私聊消息
     */
    void onPrivate(const framework::SessionPtr& session,
                  const protocol::PrivateMessage& msg,
                  muduo::Timestamp time) {
        std::lock_guard<std::mutex> lock(usersMutex_);
        
        // 查找发送者用户名
        auto senderIt = onlineUsers_.find(session->sessionId());
        if (senderIt == onlineUsers_.end()) {
            LOG_WARN << "Private message from not logged in session: " 
                     << session->sessionId();
            return;
        }
        
        std::string fromUser = senderIt->second;
        std::string toUser = msg.to();
        
        LOG_INFO << "Private message from '" << fromUser 
                 << "' to '" << toUser << "': " << msg.content();
        
        // 查找目标用户
        uint64_t targetSessionId = 0;
        for (const auto& pair : onlineUsers_) {
            if (pair.second == toUser) {
                targetSessionId = pair.first;
                break;
            }
        }
        
        if (targetSessionId == 0) {
            // 目标用户不在线
            LOG_WARN << "Target user '" << toUser << "' not found";
            
            // 可以发送错误消息给发送者
            protocol::ChatMessage errorMsg;
            errorMsg.set_from("System");
            errorMsg.set_content("User '" + toUser + "' is not online");
            errorMsg.set_timestamp(time.microSecondsSinceEpoch());
            sendToClient(session->sessionId(), protocol::MSG_CHAT, errorMsg);
            return;
        }
        
        // 构造私聊消息
        protocol::ChatMessage privateMsg;
        privateMsg.set_from(fromUser + " (private)");
        privateMsg.set_content(msg.content());
        privateMsg.set_timestamp(time.microSecondsSinceEpoch());
        
        // 发送给目标用户
        sendToClient(targetSessionId, protocol::MSG_CHAT, privateMsg);
        
        LOG_INFO << "Private message delivered to '" << toUser << "'";
    }
    
    /**
     * @brief 处理用户列表查询
     */
    void onUserList(const framework::SessionPtr& session,
                   const protocol::UserListRequest& request,
                   muduo::Timestamp time) {
        std::lock_guard<std::mutex> lock(usersMutex_);
        
        LOG_INFO << "User list request from session " << session->sessionId();
        
        // 构造用户列表响应
        protocol::UserListResponse response;
        for (const auto& pair : onlineUsers_) {
            response.add_users(pair.second);
        }
        
        // 发送响应
        sendToClient(session->sessionId(), protocol::MSG_USER_LIST_RESPONSE, response);
        
        LOG_INFO << "User list sent to session " << session->sessionId()
                 << ", total users: " << onlineUsers_.size();
    }

private:
    // 在线用户：sessionId → username
    std::unordered_map<uint64_t, std::string> onlineUsers_;
    
    // 用户列表互斥锁
    std::mutex usersMutex_;
};

} // namespace servers

